﻿#include <sstream>
#include <iomanip>
#include <cstdio>
#include "Socket.h"
#include "IOManager.h"
#include "hook.h"
/*
   1.日志系统
   2.协程库开发
   3.socket函数库
   4.http协议开发
   5.分布式协议
   6.推荐系统
   */



sylar::Loggers::ptr g_logger = SYLAR_LOG_ROOT();
/*
void testcall() {
	std::cout << sylar::LoggerMgr::GetInstance()->toJsonString()<<std::endl;

	ifstream input("/home/xxx/projects/systemp/json_config.json");
	Json::Value root;
	Json::Reader rd;
	rd.parse(input, root);
	sylar::Config::LoadFromJson(root);

	std::cout << sylar::LoggerMgr::GetInstance()->toJsonString() << std::endl;
	SYLAR_LOG_INFO(SYLAR_LOG_NAME("system"))<<"dayinsss";

}
sylar::RWMutex wr;
//sylar::Mutex mtx;
void fun1() {
	
	SYLAR_LOG_INFO(g_logger)
		<<"name: "<<sylar::Thread::GetName()
		<<"this.name: "<<sylar::Thread::GetThis()->getName() 
		<<"this_id: "<<sylar::Thread::GetThis()->getId();

	for (int i = 0; i < 10000; i++)
	{
		sylar::RWMutex::WriteLock lock(wr);
		++f_count;
	}

}

void fun2() {
	int i=0;
	auto log =SYLAR_LOG_NAME("system");
	while (10000>i) {
		i++;
		SYLAR_LOG_INFO(log);
	}

}
*/
//void test_assert() {
//
//	X_ASSERT(1);
//}
//

//void thread_test()
//{
//	sylar::Fiber::GetThis();
//	SYLAR_LOG_INFO(g_logger) << "1";
//	sylar::Fiber::ptr fiberi = std::make_shared<sylar::Fiber>(test_corotine);
//	fiberi->swapIn();
//	SYLAR_LOG_INFO(g_logger) << "3";
//	fiberi->swapIn();
//	SYLAR_LOG_INFO(g_logger) << "END";
//	fiberi->swapIn();
//}
//
//void t() {
//	sleep(1);
//	SYLAR_LOG_INFO(g_logger) << "================";
//}
//
//void V() {
//	sleep(1);
//	SYLAR_LOG_INFO(g_logger) << "VVVVVVVVVVVVVVVVV";
//	//sylar::Scheduler::GetThis()->schedule(V);
//}

//void test_fiber() 
//{
//sleep(2);
//	SYLAR_LOG_INFO(g_logger) << " sleep 2";
//}
//timer.addtimer
// Iomanager.addevent
// Iomanager.schedule
//test->start()-> schedule() -> run()->swapin ->test_fiber->idle(epoll_wait)-> TaskEvent->swapout
/*
void test() {
	
	sylar::IOManager iom;
	//iom.schedule(&test_fiber);
	int sock = socket(AF_INET, SOCK_STREAM, 0);
	fcntl(sock, F_SETFL, O_NONBLOCK);

	sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(6666);
	addr.sin_addr.s_addr = inet_addr("192.168.0.104");
	
	int rt = connect(sock, (sockaddr*)&addr,sizeof(addr));
	if(rt==0)
	{
		std::cout << " connect success " << std::endl;
	}
	else
	{
		if (errno == EINPROGRESS)//非阻塞可能触发
		{
			std::cout << " addevent " << sock << std::endl;
			iom.addEvent(sock, sylar::IOManager::READ, [&]() {

				SYLAR_LOG_INFO(g_logger) << "READ Event trigger";
				});
			
			iom.addEvent(sock, sylar::IOManager::WRITE, [&]() {
				SYLAR_LOG_INFO(g_logger) << "WRITE Event trigger";
				iom.GetThis()->cancelEvent(sock, sylar::IOManager::READ);
				});
		}
		else
		{
			std::cout << " othre error " << std::endl;
		}
	}


	}

/*
#include "http_parser.h"

void test_byte()
{
#define XXS(type,len,write_fun,read_fun,base_len) \
	std::vector<type> vec; \
	for (int i = 0; i < len; i++) \
	{ \ 
	vec.push_back(rand()); \
	} \
	sylar::ByteArray::ptr ba(new sylar::ByteArray(base_len)); \
		for (auto& i : vec) \
		{ \
			ba->write_fun(i); \
		} \
			ba->setPosition(0); \
			for (size_t i = 0; i < vec.size(); i++) \
			{ \
				type v = ba->read_fun(); \
				SYLAR_LOG_INFO(g_logger) << "i :" << i << " v:" << v << " vec:" <<vec[i]; \
			X_ASSERT(v == vec[i]); \
		} \
		X_ASSERT(ba->getReadSize() == 0); \
			SYLAR_LOG_INFO(g_logger) <<#write_fun "/" #read_fun \
			<<" ("#type") len= "<<len <<" base_len="<<base_len; \

	//XXS(uint8_t, 100, writeFuint8, readFuint8, 1);
	//XXS(uint8_t, 100, writeFuint8, readFuint8, 1);
	//XXS(int16_t, 100, writeFint16, readFint16, 1);
	//XXS(uint32_t, 100, writeFuint32, readFuint32, 1);
	//XXS(uint64_t, 100, writeFint64, readFint64, 1);
	//XXS(int32_t, 100, writeInt32, readInt32, 1);
	//XXS(int64_t, 100, writeInt64, readInt64, 1);
#undef XXS
}

char test_request_data[] = 
"GET / HTTP/1.1\r\n"
"Host: www.sylar.top\r\n"
"Content-Length: 10\r\n\r\n"
"12345678";
void test_httpParser()
{
	sylar::http::HttpRequestParser parser;
	string temp = test_request_data;
size_t s=parser.execute(&test_request_data[0],temp.size());
	SYLAR_LOG_INFO(g_logger) << "execut rt= " << s << " has_error=" << parser.hasError()
		<< " is_finished=" << parser.isFinished();
	SYLAR_LOG_INFO(g_logger) << parser.getData()->toString();
}
*/

/*

#include "Address.h"
#include "tcp_server.h"
#include "Bytearray.h"
#include "Http_Server.h"
#include "HttpConnection.h"
int m_type = 0;

class EchoServer : public sylar::TcpServer
{
public:
	using ptr = std::shared_ptr<EchoServer>;
protected:
	void handleClient(sylar::Socket::ptr client)override
	{
		SYLAR_LOG_INFO(g_logger) << "handleClient";
		sylar::ByteArray::ptr ba(new sylar::ByteArray());

		while (true)
		{
			ba->clear();
			std::vector<iovec> iovs;
			ba->getWriteBuffers(iovs, 1024);
			int n = client->recv(&iovs[0], iovs.size());
			if (n == 0)
			{
				SYLAR_LOG_INFO(g_logger) << " Client close:"<< *client;
				break;
			}
			else if(n < 0)
			{
				SYLAR_LOG_INFO(g_logger) << " fail Client :" << *client;
				break;
			}
			//正常的话将写入缓冲区
			ba->setPosition(ba->getPosition() +  1024);
			ba->setPosition(0);
		//	SYLAR_LOG_INFO(g_logger) << std::string((char*)iovs[0].iov_base,n);
			

			if (m_type == 1)
			{
				//文本
				SYLAR_LOG_INFO(g_logger) << ba->toString()<<"";
				std::cout.flush();
			}
			else
			{
				//二进制
				SYLAR_LOG_INFO(g_logger) << ba->toHexString()<<"";
				std::cout << std::endl;
			}
		}
	}

};


void run()
{
	SYLAR_LOG_INFO(g_logger) << "IN TO";

auto addr=sylar::Address::LookupAny("192.168.1.1:80");

sylar::http::HttpRequest::ptr req(new sylar::http::HttpRequest);
req->setMethod(sylar::http::HttpMethod::GET);
req->setPath("/");

req->setHeader("host", "192.168.1.1");
req->setHeader("connection", "keep-alive");
auto resul = sylar::http::HttpConnection::AddDoRequst(req, addr);
//auto uri = sylar::URI::CreateURI("https://haowallpaper.com:443/homeView?isSel=true&page=55");
//auto resul = sylar::http::HttpConnection::DoRequst(sylar::http::HttpMethod::POST,uri,std::map<std::string,std::string>());


//ofstream ss("response.http");
ss << *resul->response;

SYLAR_LOG_INFO(g_logger) << resul->response->toString();



vector<sylar::Address::ptr> addrs;
vector<sylar::Address::ptr> fail;
addrs.push_back(addr);


*/

//auto servlet = tcpservers->getServletDispatch();
//servlet->addServlet("/xxx", [](sylar::http::HttpRequest::ptr req,sylar::http::HttpResponse::ptr rsp, sylar::http::HttpSession::ptr)->int32_t {
//	rsp->setBody("xxxx");
//	return 0;
//	}); 
//while (!tcpservers->bind(addrs, fail))
//{
//	SYLAR_LOG_INFO(g_logger) << "bind fail .............";
//	sleep(10);
//}
//tcpservers->start();

//}


/*
void hookto()
{
	SYLAR_LOG_INFO(g_logger) << "SLEEP 开始 2";
	sleep(2);
	SYLAR_LOG_INFO(g_logger) << "SLEEP 2";

	int sock = socket(AF_INET, SOCK_STREAM, 0);
	
	sockaddr_in addrsock;
	addrsock.sin_addr = { INADDR_ANY };
	addrsock.sin_family = AF_INET;
	addrsock.sin_port = htons(8669);
	bind(sock, (sockaddr*)&addrsock, sizeof(addrsock));
	listen(sock, 10);
	accept(sock, 0, 0);

	SYLAR_LOG_INFO(g_logger) << " Accept success ";

	close(sock);
}

void hook_tast()
{
	SYLAR_LOG_INFO(g_logger) << "BEING";
	sylar::IOManager iom(1,true,"Iom");
	iom.schedule(&hookto);

}
*/
#include "http.h"
#include "HttpConnection.h"

/*
void https_socket()
{
	sylar::http::HttpRequest::ptr req = std::make_shared<sylar::http::HttpRequest>();
	req->setHeader("Host", "chat.deepseek.com");
	req->setHeader("Connection", "keep-alive");

auto uri = sylar::URI::CreateURI("https://chat.deepseek.com/a/chat/s/ca5aec4e-9b73-4b5c-a822-5535c071aeb8");
auto result = sylar::http::HttpConnection::DoRequst(req,uri,true);

SYLAR_LOG_INFO(g_logger) << "Body:" <<result->response->getBody();
}
*/

#include "Websock.h"
#include <openssl/sha.h>
#include "HttpSession.h"
#include "Http_Server.h"

//sock连接->http连接->websocket->ws_session->ws_paser
void websocketTest()
{

	//sylar::Address addr;
	sockaddr_in sadd;
	sadd.sin_addr.s_addr=inet_addr("192.168.81.200");
	sadd.sin_family = AF_INET;
	sadd.sin_port = htons(8888);
	auto addr = sylar::Address::Create((sockaddr*)&sadd, sizeof(sadd));
	
	sylar::http::Web_Server::ptr server(new sylar::http::Web_Server());
	if (!server->bind(addr))
	{
		SYLAR_LOG_INFO(g_logger) << "bind false";
	}
	server->start();
	


	//server->stop();

	
}


int main(int argc,char **argv)
{

	//m_type = 1;
	SYLAR_LOG_INFO(g_logger) << "BEING";
	sylar::IOManager iom(1, true, "Iom");
	//iom.schedule(&https_socket);
	iom.schedule(websocketTest);
	
	
	//hook_tast();

	//test_httpParser();
	//test_byte();
	//test_hook();
	//test();


	return 0;

}
